package com.fzg.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzg.common.enums.ResponseWrapper;
import com.fzg.common.model.param.blog.AddOrEditBlogParam;
import com.fzg.common.model.param.blog.CommentPublishBlogParam;
import com.fzg.common.model.param.diary.GetDiaryListParam;
import com.fzg.common.model.result.blog.GetBlogListByUserAid;
import com.fzg.common.model.result.blog.GetBlogListResult;
import com.fzg.common.model.result.blog.UserBlogResultDto;
import com.fzg.common.tool.JwtUtil;
import com.fzg.common.tool.Medthods;
import com.fzg.common.tool.ToolForDateTime;
import com.fzg.entity.*;
import com.fzg.mapper.*;
import com.fzg.service.BlogService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author fzg
 * @since 2022-06-20
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private UserCollectMapper userCollectMapper;

    @Autowired
    BlogCommentMapper blogCommentMapper;

    @Autowired
    UserGuanzhuMapper userGuanzhuMapper;

    @Autowired
    private BlogDianzanMapper blogDianzanMapper;

    @Autowired
    private BlogCommentDianzanMapper blogCommentDianzanMapper;


    /**
     * @name 方法名：getMyselfBlogList
     * @description todo: 获取自己的博客列表
     *
     * @param request 参数：HttpServletRequest
     * @param param   参数：param
     * @return ResponseWrapper
     * @date 2022/12/26 11:43
     * @author fzg
     **/
    @Override
    public ResponseWrapper getMyselfBlogList(HttpServletRequest request, GetDiaryListParam param) {
        // 获取token
        String token = request.getHeader("token");
        Integer userAid = JwtUtil.getTokenId(token);
        ArrayList<GetBlogListResult> result = new ArrayList<>();

        if (param.getTimerValue().equals("-1")){
            // 查询全部
            if (param.getDiaryTimeTypeValue().equals(0)){
                List<Blog> blogListAll = blogMapper.selectList(new LambdaQueryWrapper<Blog>()
                        .eq(Blog::getUserAid, userAid)
                        .orderByDesc(Blog::getCreateTime)
                );
                for (Blog blog : blogListAll) {
                    GetBlogListResult blogReuslt = new GetBlogListResult();
                    blogReuslt.setBlogAid(blog.getAid());
                    blogReuslt.setUserAid(blog.getUserAid());
                    // 日记图片有很多张或者没有或者只有 一张
                    blogReuslt.setBlogImg(Medthods.imageUrlsSplitToFirstUrl(blog.getBlogImgurl()));

                    blogReuslt.setContent(blog.getContent());
                    String timeToString = ToolForDateTime.LocalDateTimeToString(blog.getCreateTime());
                    if (timeToString.charAt(5) == '0'){
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(6,7)));
                    }else {
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(5,7)));
                    }
                    if (timeToString.charAt(8) == '0'){
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(9,10)));
                    }else {
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(8,10)));
                    }
                    blogReuslt.setDayTime(timeToString.substring(11,16));
                    result.add(blogReuslt);
                }
                return ResponseWrapper.markSuccess(result);
            }else if (param.getDiaryTimeTypeValue().equals(1)){
                // 查询本周
                LocalDateTime now = LocalDateTime.now();
                // 本周第一天
                LocalDateTime weekFirstDay = now.with(DayOfWeek.MONDAY);
                List<Blog> blogListWeek = blogMapper.selectList(new LambdaQueryWrapper<Blog>()
                        .eq(Blog::getUserAid, userAid)
                        .between(Blog::getCreateTime, weekFirstDay, now)
                        .orderByDesc(Blog::getCreateTime)
                );
                for (Blog blog : blogListWeek) {
                    GetBlogListResult blogReuslt = new GetBlogListResult();
                    blogReuslt.setBlogAid(blog.getAid());
                    blogReuslt.setUserAid(blog.getUserAid());
                    // 日记图片有很多张或者没有或者只有 一张
                    blogReuslt.setBlogImg(Medthods.imageUrlsSplitToFirstUrl(blog.getBlogImgurl()));
                    blogReuslt.setContent(blog.getContent());
                    String timeToString = ToolForDateTime.LocalDateTimeToString(blog.getCreateTime());
                    if (timeToString.charAt(5) == '0'){
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(6,7)));
                    }else {
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(5,7)));
                    }
                    if (timeToString.charAt(8) == '0'){
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(9,10)));
                    }else {
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(8,10)));
                    }
                    blogReuslt.setDayTime(timeToString.substring(11,16));
                    result.add(blogReuslt);
                }
                return ResponseWrapper.markSuccess(result);
            }else if (param.getDiaryTimeTypeValue().equals(2)){  // 查询本月
                LocalDateTime now = LocalDateTime.now();
                // 本月第一天
                LocalDateTime monthFirstDay = now.with(TemporalAdjusters.firstDayOfMonth());
                List<Blog> blogListMonth = blogMapper.selectList(new LambdaQueryWrapper<Blog>()
                        .eq(Blog::getUserAid, userAid)
                        .between(Blog::getCreateTime, monthFirstDay, now)
                        .orderByDesc(Blog::getCreateTime)
                );
                for (Blog blog : blogListMonth) {
                    GetBlogListResult blogReuslt = new GetBlogListResult();
                    blogReuslt.setBlogAid(blog.getAid());
                    blogReuslt.setUserAid(blog.getUserAid());
                    // 日记图片有很多张或者没有或者只有 一张
                    blogReuslt.setBlogImg(Medthods.imageUrlsSplitToFirstUrl(blog.getBlogImgurl()));

                    blogReuslt.setContent(blog.getContent());
                    String timeToString = ToolForDateTime.LocalDateTimeToString(blog.getCreateTime());
                    if (timeToString.charAt(5) == '0'){
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(6,7)));
                    }else {
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(5,7)));
                    }
                    if (timeToString.charAt(8) == '0'){
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(9,10)));
                    }else {
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(8,10)));
                    }
                    blogReuslt.setDayTime(timeToString.substring(11,16));
                    result.add(blogReuslt);
                }
                return ResponseWrapper.markSuccess(result);
            }else if (param.getDiaryTimeTypeValue().equals(3)){
                LocalDateTime now = LocalDateTime.now();
                // 今年第一天
                LocalDateTime CurrentYearFirstDay = now.with(TemporalAdjusters.firstDayOfYear());
                List<Blog> blogListCurrentYear = blogMapper.selectList(new LambdaQueryWrapper<Blog>()
                        .eq(Blog::getUserAid, userAid)
                        .between(Blog::getCreateTime, CurrentYearFirstDay, now)
                        .orderByDesc(Blog::getCreateTime)
                );
                for (Blog blog : blogListCurrentYear) {
                    GetBlogListResult blogReuslt = new GetBlogListResult();
                    blogReuslt.setBlogAid(blog.getAid());
                    blogReuslt.setUserAid(blog.getUserAid());
                    // 日记图片有很多张或者没有或者只有 一张
                    blogReuslt.setBlogImg(Medthods.imageUrlsSplitToFirstUrl(blog.getBlogImgurl()));
                    blogReuslt.setContent(blog.getContent());
                    String timeToString = ToolForDateTime.LocalDateTimeToString(blog.getCreateTime());
                    if (timeToString.charAt(5) == '0'){
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(6,7)));
                    }else {
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(5,7)));
                    }
                    if (timeToString.charAt(8) == '0'){
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(9,10)));
                    }else {
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(8,10)));
                    }
                    blogReuslt.setDayTime(timeToString.substring(11,16));
                    result.add(blogReuslt);
                }
                return ResponseWrapper.markSuccess(result);
            }else if (param.getDiaryTimeTypeValue().equals(4)){  // 去年
                LocalDateTime now = LocalDateTime.now();
                String lastYeay = String.valueOf(Integer.parseInt(now.toString().substring(0, 4)) - 1);
                List<Blog> blogListLastYeay = blogMapper.selectList(new LambdaQueryWrapper<Blog>()
                        .eq(Blog::getUserAid, userAid)
                        .likeRight(Blog::getCreateTime, lastYeay)
                        .orderByDesc(Blog::getCreateTime)
                );
                for (Blog blog : blogListLastYeay) {
                    GetBlogListResult blogReuslt = new GetBlogListResult();
                    blogReuslt.setBlogAid(blog.getAid());
                    blogReuslt.setUserAid(blog.getUserAid());
                    // 日记图片有很多张或者没有或者只有 一张
                    blogReuslt.setBlogImg(Medthods.imageUrlsSplitToFirstUrl(blog.getBlogImgurl()));
                    blogReuslt.setContent(blog.getContent());
                    String timeToString = ToolForDateTime.LocalDateTimeToString(blog.getCreateTime());
                    if (timeToString.charAt(5) == '0'){
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(6,7)));
                    }else {
                        blogReuslt.setMonth(Integer.parseInt(timeToString.substring(5,7)));
                    }
                    if (timeToString.charAt(8) == '0'){
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(9,10)));
                    }else {
                        blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(8,10)));
                    }
                    blogReuslt.setDayTime(timeToString.substring(11,16));
                    result.add(blogReuslt);
                }
                return ResponseWrapper.markSuccess(result);
            }
        }else {  // 时间选择器有值
            List<Blog> blogList = blogMapper.selectList(new LambdaQueryWrapper<Blog>()
                    .eq(Blog::getUserAid, userAid)
                    .likeRight(Blog::getCreateTime, param.getTimerValue())
                    .orderByDesc(Blog::getCreateTime)
            );
            for (Blog blog : blogList) {
                GetBlogListResult blogReuslt = new GetBlogListResult();
                blogReuslt.setBlogAid(blog.getAid());
                blogReuslt.setUserAid(blog.getUserAid());
                // 日记图片有很多张或者没有或者只有 一张
                blogReuslt.setBlogImg(Medthods.imageUrlsSplitToFirstUrl(blog.getBlogImgurl()));

                blogReuslt.setContent(blog.getContent());
                String timeToString = ToolForDateTime.LocalDateTimeToString(blog.getCreateTime());
                if (timeToString.charAt(5) == '0') {
                    blogReuslt.setMonth(Integer.parseInt(timeToString.substring(6, 7)));
                } else {
                    blogReuslt.setMonth(Integer.parseInt(timeToString.substring(5, 7)));
                }
                if (timeToString.charAt(8) == '0') {
                    blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(9, 10)));
                } else {
                    blogReuslt.setHaoDate(Integer.parseInt(timeToString.substring(8, 10)));
                }
                blogReuslt.setDayTime(timeToString.substring(11, 16));
                result.add(blogReuslt);
            }
            return ResponseWrapper.markSuccess(result);
        }
        return ResponseWrapper.markSuccess(new ArrayList<>());
    }

    /**
     * @name 方法名：getBlogListByUserAid
     * @description todo: 通过用户aid查询博客列表
     *
     * @param userAid 用户aid
     * @return ResponseWrapper
     * @date 2022/12/26 11:47
     * @author fzg
     **/
    @Override
    public ResponseWrapper getBlogListByUserAid(Integer userAid) {
        GetBlogListByUserAid result = new GetBlogListByUserAid();
        User user = userMapper.selectById(userAid);

        // 这个用户全部信息
        result.setUser(user);

        // 这个用户的博客列表
        ArrayList<UserBlogResultDto> blogList = new ArrayList<>();
        List<Blog> blogs = blogMapper.selectList(new LambdaQueryWrapper<Blog>()
                .eq(Blog::getUserAid, userAid)
        );
        for (Blog blog : blogs) {
            UserBlogResultDto userBlog = new UserBlogResultDto();
            userBlog.setBlogAid(blog.getAid());
            userBlog.setContent(blog.getContent());
            userBlog.setCreateTime(blog.getCreateTime().toString().substring(0,10) + " " + blog.getCreateTime().toString().substring(11));
            userBlog.setImageList(Medthods.imageStrSplitToArrayList(blog.getBlogImgurl()));
            blogList.add(userBlog);
        }

        result.setBlogList(blogList);
        return ResponseWrapper.markSuccess(result);

    }


    /**
     * @name 方法名：getAllBlogInfoByUserAid
     * @description todo: 根据博客aid查询博客相关所有信息（包括博客，评论等）
     *
     * @param request 参数：HttpServletRequest
     * @param blogAid 参数：博客aid
     * @return ResponseWrapper
     * @date 2022/12/26 11:48
     * @author fzg
     **/
    @Override
    public ResponseWrapper getAllBlogInfoByUserAid(HttpServletRequest request, Integer blogAid) {
        // 返回结果数据
        HashMap<String, Object> result = new HashMap<>();

        // 根据博客aid查询博客
        Blog blog = blogMapper.selectById(blogAid);

        // 这条博客的作者aid
        result.put("authorAid",blog.getUserAid());

        // 这条博客的作者头像
        User user = userMapper.selectById(blog.getUserAid());
        if (user.getAvatar() != null){
            result.put("authorAvatar",user.getAvatar());
        }else {
            // 用户头像没有就设置一个默认头像
            result.put("authorAvatar","https://img1.baidu.com/it/u=905482077,1717804812&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500");
        }

        // 这条博客的作者昵称
        if (user.getNickName() != null){
            result.put("nickName",user.getNickName());
        }else {
            // 作者昵称为空就设置为用户名
            result.put("nickName",user.getUserName());
        }

        // 这条博客的标签
        result.put("tags",blog.getTags());

        // 这条博客是否是当前登陆的用户写的
        Integer currentUserAid = JwtUtil.getTokenId(request.getHeader("token"));
        result.put("authorIsCurrentUser",currentUserAid.equals(user.getAid()));

        // 当前登陆用户是否收藏了这条博客
        List<UserCollect> userCollects = userCollectMapper.selectList(new LambdaQueryWrapper<UserCollect>()
                .eq(UserCollect::getUserAid, currentUserAid)
                .eq(UserCollect::getCollectType, 2)
                .eq(UserCollect::getContentAid, blogAid)
        );
        result.put("isCollect",userCollects.size()>0);

        // 博客的内容
        result.put("blogContent",blog.getContent());

        // 这条博客的评论数量
        List<BlogComment> blogComments = blogCommentMapper.selectList(new LambdaQueryWrapper<BlogComment>().eq(BlogComment::getBlogAid, blogAid));
        result.put("commentNum",blogComments.size());

        // 博客的照片
        result.put("blogImageList",Medthods.imageStrSplitToArrayList(blog.getBlogImgurl()));

        // 博客的发布时间(格式： 2022年12月1日 14:52)
        LocalDateTime time = blog.getCreateTime();
        // 转string
        System.out.println(time.toString().substring(11,16));
        // LocalDateTime转yyyy-MM-dd
        String time1 = ToolForDateTime.LocalDateTimeToStringToDate(time);
        // yyyy-MM-dd转x年x月x日
        String timer2 = ToolForDateTime.StringDateToYearMonthDay(time1);
        // 时间部分
        String time3 = time.toString().substring(11, 16);
        // 最后返回的发布时间
        result.put("blogPublishTime",timer2 + " " + time3);

        // 博客的点赞数量
        result.put("likesNum",blog.getLikeNum());

        // 是否关注了这条博客的作者
        List<UserGuanzhu> myselfGuanzhuUserList = userGuanzhuMapper.selectList(new LambdaQueryWrapper<UserGuanzhu>()
                .eq(UserGuanzhu::getGuanzhuUserAid, currentUserAid)
        );
        boolean isGuanzhu = false;
        for (UserGuanzhu userGuanzhu : myselfGuanzhuUserList) {
            if (user.getAid().equals(userGuanzhu.getBeiguanzhuUserAid())){
                isGuanzhu = true;
                break;
            }
        }
        result.put("isGuanzhu",isGuanzhu);

        // 是否点赞了这条博客
        List<BlogDianzan> blogDianzans = blogDianzanMapper.selectList(new LambdaQueryWrapper<BlogDianzan>()
                .eq(BlogDianzan::getUserAid, currentUserAid)
        );
        boolean isDianZan = false;
        for (BlogDianzan blogDianzan : blogDianzans) {
            if (blogDianzan.getBlogAid().equals(blog.getAid())){
                isDianZan = true;
                break;
            }
        }
        result.put("isDianZan",isDianZan);

        // 博客的评论列表
        result.put("blogCommentList",this.getDiaryCommentTree(blog,currentUserAid));

        return ResponseWrapper.markSuccess(result);
    }

    /**
     * @name 方法名：dianzanBlog
     * @description todo: 当前登陆的用户给这条博客点赞
     *
     * @param request 参数：HttpServletRequest
     * @param aid 参数：博客aid
     * @return ResponseWrapper
     * @date 2022/12/26 11:56
     * @author fzg
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper dianzanBlog(HttpServletRequest request, Integer aid) {
        // 给这条博客赞的数量加1
        Blog blog = blogMapper.selectById(aid);
        Blog blog1 = new Blog();
        BeanUtils.copyProperties(blog,blog1);
        blog1.setLikeNum(blog.getLikeNum() + 1);
        blogMapper.updateById(blog1);

        // 点赞
        blogDianzanMapper.insert(new BlogDianzan(){{
            setUserAid(JwtUtil.getTokenId(request.getHeader("token")));
            setBlogAid(aid);
        }});
        return ResponseWrapper.markSuccess();
    }

    /**
     * @name 方法名：cancelDianzanBlog
     * @description todo: 当前登陆用户给这条博客取消点赞
     *
     * @param request 参数：HttpServletRequest
     * @param aid 参数：博客aid
     * @return ResponseWrapper
     * @date 2022/12/26 12:00
     * @author fzg
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper cancelDianzanBlog(HttpServletRequest request, Integer aid) {
        // 给这条日记赞的数量-1
        Blog blog = blogMapper.selectById(aid);
        Blog blog1 = new Blog();
        BeanUtils.copyProperties(blog,blog1);
        if (blog.getLikeNum() > 0){
            blog1.setLikeNum(blog.getLikeNum() - 1);
        }else {
            blog1.setLikeNum(0);
        }
        blogMapper.updateById(blog1);

        // 取消点赞
        blogDianzanMapper.delete(new LambdaQueryWrapper<BlogDianzan>()
                .eq(BlogDianzan::getUserAid,JwtUtil.getTokenId(request.getHeader("token")))
                .eq(BlogDianzan::getBlogAid,aid)
        );
        return ResponseWrapper.markSuccess();
    }

    /**
     * @name 方法名：clickCommentLike
     * @description todo: 点击评论里面的赞，改变赞的状态
     *
     * @param request 参数：HttpServletRequest
     * @param aid 参数：评论aid
     * @return ResponseWrapper
     * @date 2022/12/26 13:10
     * @author fzg
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper clickCommentLike(HttpServletRequest request, Integer aid) {
        // 获取当前登陆的用户aid
        Integer currentUserAid = JwtUtil.getTokenId(request.getHeader("token"));

        BlogCommentDianzan blogCommentDianzan = blogCommentDianzanMapper.selectOne(new LambdaQueryWrapper<BlogCommentDianzan>()
                .eq(BlogCommentDianzan::getUserAid, currentUserAid)
                .eq(BlogCommentDianzan::getCommentAid, aid)
        );
        if (blogCommentDianzan != null){
            System.out.println("fzg=>  " + blogCommentDianzan.getAid());
            // 说明已经赞过了，
            blogCommentDianzanMapper.delete(new LambdaQueryWrapper<BlogCommentDianzan>()
                    .eq(BlogCommentDianzan::getUserAid, currentUserAid)
                    .eq(BlogCommentDianzan::getCommentAid, aid)
            );
            // 获赞数-1
            com.fzg.entity.BlogComment blogComment = blogCommentMapper.selectById(aid);
            blogComment.setLikesCount(blogComment.getLikesCount() - 1);
            blogCommentMapper.updateById(blogComment);
        }else {
            // 说明还没赞过
            blogCommentDianzanMapper.insert(new BlogCommentDianzan(){{
                setUserAid(currentUserAid);
                setCommentAid(aid);
            }});
            // 日记评论的获赞数+1
            com.fzg.entity.BlogComment blogComment = blogCommentMapper.selectById(aid);
            blogComment.setLikesCount(blogComment.getLikesCount() + 1);
            blogCommentMapper.updateById(blogComment);
        }
        return ResponseWrapper.markSuccess();
    }

    /**
     * @name 方法名：blogCommentPublish
     * @description todo: 发表评论
     *
     * @param request 参数：HttpServletRequest
     * @param param 参数类：CommentPublishBlogParam
     * @return ResponseWrapper
     * @date 2022/12/26 13:12
     * @author fzg
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper blogCommentPublish(HttpServletRequest request, CommentPublishBlogParam param) {
        int insert = blogCommentMapper.insert(new com.fzg.entity.BlogComment() {{
            setUserAid(JwtUtil.getTokenId(request.getHeader("token")));
            setBlogAid(param.getBlogAid());
            setCommentContent(param.getCommentContent());
            setParentAid((param.getCommentParentAid() == null || param.getCommentParentAid() == -1) ? null : param.getCommentParentAid());
            setLikesCount(Long.parseLong("0"));
        }});
        if (insert > 0){
            return ResponseWrapper.markCustomSuccess("发表成功！");
        }else {
            return ResponseWrapper.markCustomError("发表失败！");
        }
    }


    /**
     * @name 方法名：collectBlog
     * @description todo: 点击收藏，收藏这个博客
     *
     * @param request 参数：HttpServletRequest
     * @param blogAid 参数：博客aid
     * @return ResponseWrapper
     * @date 2022/12/26 14:09
     * @author fzg
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper collectBlog(HttpServletRequest request, Integer blogAid) {
        int insert = userCollectMapper.insert(new UserCollect() {{
            setUserAid(JwtUtil.getTokenId(request.getHeader("token")));
            setCollectType(2);
            setContentAid(blogAid);
        }});
        if (insert > 0){
            return ResponseWrapper.markCustomSuccess("收藏成功！");
        }else {
            return ResponseWrapper.markCustomError("收藏失败！请稍后再试！");
        }
    }


    /**
     * 点击取消收藏这个博客
     *
     * @param request 参数
     * @param blogAid 参数
     * @return ResponseWrapper
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper cancelCollectBlog(HttpServletRequest request, Integer blogAid) {
        List<UserCollect> userCollects = userCollectMapper.selectList(new LambdaQueryWrapper<UserCollect>()
                .eq(UserCollect::getUserAid, JwtUtil.getTokenId(request.getHeader("token")))
                .eq(UserCollect::getCollectType, 2)
                .eq(UserCollect::getContentAid, blogAid)
        );
        for (UserCollect userCollect : userCollects) {
            userCollectMapper.deleteById(userCollect);
        }
        return ResponseWrapper.markSuccess();
    }

    /**
     * 关注这个博客的作者
     *
     * @param request 参数
     * @param blogAid 参数
     * @return ResponseWrapper
     */
    @Override
    public ResponseWrapper guanzhuBlogAuthor(HttpServletRequest request, Integer blogAid) {
        Blog blog = blogMapper.selectById(blogAid);
        int insert = userGuanzhuMapper.insert(new UserGuanzhu() {{
            setGuanzhuUserAid(JwtUtil.getTokenId(request.getHeader("token")));
            setBeiguanzhuUserAid(blog.getUserAid());
        }});
        if (insert > 0){
            return ResponseWrapper.markCustomSuccess("关注成功！");
        }else {
            return ResponseWrapper.markCustomError("关注失败，请稍后再试！");
        }
    }

    /**
     * 取消关注这个博客的作者
     *
     * @param request 参数
     * @param blogAid 参数
     * @return ResponseWrapper
     */
    @Override
    public ResponseWrapper cancelGuanzhuBlogAuthor(HttpServletRequest request, Integer blogAid) {
        Blog blog = blogMapper.selectById(blogAid);
        int delete = userGuanzhuMapper.delete(new LambdaQueryWrapper<UserGuanzhu>()
                .eq(UserGuanzhu::getGuanzhuUserAid, JwtUtil.getTokenId(request.getHeader("token")))
                .eq(UserGuanzhu::getBeiguanzhuUserAid, blog.getUserAid())
        );
        if (delete > 0){
            return ResponseWrapper.markCustomSuccess("已取消关注！");
        }else {
            return ResponseWrapper.markCustomError("操作失败，请稍后再试！");
        }
    }

    /**
     * 添加或者编辑博客
     *
     * @param request 参数
     * @param param 参数
     * @return ResponseWrapper
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper addOrEditBlog(HttpServletRequest request, AddOrEditBlogParam param) {
        if (param.getBlogAid().equals(-1)){
            int insert = blogMapper.insert(new Blog() {{
                setUserAid(JwtUtil.getTokenId(request.getHeader("token")));
                setBlogImgurl(param.getImageUrls());
                setContent(param.getContent());
                setLikeNum(0);
                setIsPublish(param.getPublished());
                setTags(param.getTag());
            }});
            if (insert > 0){
                if (param.getPublished().equals(0)){
                    return ResponseWrapper.markCustomSuccess("日记已保存为草稿！");
                }else {
                    return ResponseWrapper.markCustomSuccess("日记发表成功！");
                }
            }else {
                return ResponseWrapper.markCustomError("添加失败！");
            }
        }else {
            Blog blog = blogMapper.selectById(param.getBlogAid());
            blog.setContent(param.getContent());
            blog.setTags(param.getTag());
            blog.setBlogImgurl(param.getImageUrls());
            blog.setIsPublish(param.getPublished());
            int updateById = blogMapper.updateById(blog);
            if (updateById > 0){
                return ResponseWrapper.markCustomSuccess("日记更新成功！");
            }else {
                return ResponseWrapper.markCustomError("更新失败！");
            }
        }
    }

    /**
     * 获取系统给当前登陆的用户推荐的所有日记列表
     *
     * @param request 参数
     * @return ResponseWrapper
     */
    @Override
    public ResponseWrapper getRecommentBlogList(HttpServletRequest request) {
        List<Blog> blogs = blogMapper.selectList(new LambdaQueryWrapper<Blog>().orderByDesc(Blog::getCreateTime));
        ArrayList<Object> result = new ArrayList<>();
        for (Blog blog : blogs) {
            HashMap<String, Object> item = new HashMap<>();
            item.put("blogAid",blog.getAid());
            User user = userMapper.selectById(blog.getUserAid());
            item.put("userAid",user.getAid());
            item.put("userName",user.getUserName());
            item.put("userNickName",(user.getNickName() == null || user.getNickName().equals("")) ? user.getUserName() : user.getNickName());
            item.put("avatar",(user.getAvatar() == null || user.getAvatar().equals("")) ? "https://img1.baidu.com/it/u=3866475743,1893693583&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400" : user.getAvatar());

            // 博客发布时间
            item.put("time",ToolForDateTime.StringDateToYearMonthDay(
                    ToolForDateTime.LocalDateTimeToStringToDate(blog.getCreateTime()))
                    + " " +
                    blog.getCreateTime().toString().substring(11,16)
            );

            // 博客内容
            item.put("content",(blog.getContent()== null || blog.getContent().equals("")) ? "" : blog.getContent());

            // 这条博客的图片list
            // 博客包含的图片地址（有可能没有，有可能只有一张，有可能有一张以上：地址之间以;隔开）
            item.put("imageList",Medthods.imageStrSplitToArrayList(blog.getBlogImgurl()));

            // 作者是否点赞了这条博客
            List<BlogDianzan> blogDianzans = blogDianzanMapper.selectList(new LambdaQueryWrapper<BlogDianzan>()
                    .eq(BlogDianzan::getBlogAid, blog.getAid())
                    .eq(BlogDianzan::getUserAid, JwtUtil.getTokenId(request.getHeader("token")))
            );
            item.put("isLike", blogDianzans.size() > 0);

            // 这条博客的获赞数
            item.put("likesNumber",blog.getLikeNum());
            // 这条博客的作者是否是当前登陆的用户
            item.put("isCurrentUser",JwtUtil.getTokenId(request.getHeader("token")).equals(blog.getUserAid()));
            result.add(item);
        }
        return ResponseWrapper.markSuccess(result);
    }

    /**
     * 获取当前登陆这个用户关注的所有用户的所有博客列表
     *
     * @param request 参数
     * @return ResponseWrapper
     */
    @Override
    public ResponseWrapper getCurrentUserConcernUserBlogList(HttpServletRequest request) {
        // 获取当前登录用户的aid
        Integer currentUserAid = JwtUtil.getTokenId(request.getHeader("token"));

        // 先把当前登陆用户关注的用户查出来
        List<UserGuanzhu> guanzhus = userGuanzhuMapper.selectList(new LambdaQueryWrapper<UserGuanzhu>()
                .eq(UserGuanzhu::getGuanzhuUserAid, currentUserAid)
        );

        ArrayList<Blog> blogs = new ArrayList<>();
        for (UserGuanzhu userGuanzhu : guanzhus) {
            blogs.addAll(blogMapper.selectList(new LambdaQueryWrapper<Blog>()
                    .eq(Blog::getUserAid,userGuanzhu.getBeiguanzhuUserAid())
            ));
        }
        // 将blogs按照日期降序
        blogs.sort((t1, t2) -> t2.getCreateTime().compareTo(t1.getCreateTime()));

        // 返回结果
        ArrayList<Object> result = new ArrayList<>();

        for (Blog blog : blogs) {
            HashMap<String, Object> item = new HashMap<>();
            item.put("blogAid",blog.getAid());
            User user = userMapper.selectById(blog.getUserAid());
            item.put("userAid",user.getAid());
            item.put("userName",user.getUserName());
            item.put("userNickName",(user.getNickName().equals("") || user.getNickName() == null) ? user.getUserName() : user.getNickName());
            item.put("avatar",(user.getAvatar().equals("") || user.getAvatar() == null) ? "https://img1.baidu.com/it/u=3866475743,1893693583&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400" : user.getAvatar());

            // 博客的发布时间(2022年12月1日 14:52)
            LocalDateTime time = blog.getCreateTime();
            // LocalDateTime转yyyy-MM-dd
            String time1 = ToolForDateTime.LocalDateTimeToStringToDate(time);
            // yyyy-MM-dd转x年x月x日
            String timer2 = ToolForDateTime.StringDateToYearMonthDay(time1);
            // 时间部分
            String time3 = time.toString().substring(11, 16);
            // 最后返回的发布时间
            item.put("time",timer2 + " " + time3);

            // 这条博客的内容
            item.put("content",(blog.getContent().equals("") || blog.getContent() == null) ? "" : blog.getContent());

            // 这条博客的图片list
            // 博客包含的图片地址（有可能没有，有可能只有一张，有可能有一张以上：地址之间以;隔开）
            item.put("imageList",Medthods.imageStrSplitToArrayList(blog.getBlogImgurl()));

            // 作者是否点赞了这条博客
            List<BlogDianzan> blogDianzans = blogDianzanMapper.selectList(new LambdaQueryWrapper<BlogDianzan>()
                    .eq(BlogDianzan::getBlogAid, blog.getAid())
                    .eq(BlogDianzan::getUserAid, currentUserAid)
            );
            item.put("isLike",blogDianzans.size() > 0);

            // 这条博客的获赞数
            item.put("likesNumber",blog.getLikeNum());

            result.add(item);
        }
        return ResponseWrapper.markSuccess(result);
    }

    /**
     * 获取博客评论的树
     * @return ResponseWrapper
     */
    public List<com.fzg.common.model.result.blog.BlogComment> getDiaryCommentTree(Blog blog, Integer currentLoginUserAid){
        ArrayList<com.fzg.common.model.result.blog.BlogComment> blogCommentList = new ArrayList<>();
        List<com.fzg.entity.BlogComment> comments = blogCommentMapper.selectList(new LambdaQueryWrapper<BlogComment>()
                .eq(com.fzg.entity.BlogComment::getBlogAid, blog.getAid())
                .orderByDesc(com.fzg.entity.BlogComment::getCreateTime)
        );
        for (com.fzg.entity.BlogComment comment : comments) {
            com.fzg.common.model.result.blog.BlogComment blogComment = new com.fzg.common.model.result.blog.BlogComment();
            blogComment.setCommentAid(comment.getAid());
            blogComment.setCommentUserAid(comment.getUserAid());
            User user1 = userMapper.selectById(comment.getUserAid());
            if (user1.getAvatar() != null){
                blogComment.setCommentUserAvatar(user1.getAvatar());
            }else {
                blogComment.setCommentUserAvatar("https://img2.baidu.com/it/u=180286244,263138673&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500");
            }
            // 评论这条博客人的昵称
            if (user1.getNickName() == null){
                blogComment.setNickName(user1.getUserName());
            }else {
                blogComment.setNickName(user1.getNickName());
            }
            blogComment.setCommentLikesCount(Integer.parseInt(comment.getLikesCount().toString()));
            // 评论时间（格式：2022年12月1日 14:52）
            blogComment.setCommentTime(
                    ToolForDateTime.StringDateToYearMonthDay(
                            ToolForDateTime.LocalDateTimeToStringToDate(comment.getCreateTime())
                    ) + " " + comment.getCreateTime().toString().substring(11, 16)
            );
            // 当前登陆用户是否给这条评论点赞了
            List<BlogCommentDianzan> blogCommentDianzans = blogCommentDianzanMapper.selectList(new LambdaQueryWrapper<BlogCommentDianzan>()
                    .eq(BlogCommentDianzan::getUserAid, currentLoginUserAid)
            );
            boolean isUserDianZanDiaryComment = false;
            for (BlogCommentDianzan blogCommentDianzan : blogCommentDianzans) {
                if (blogCommentDianzan.getCommentAid().equals(comment.getAid())){
                    isUserDianZanDiaryComment = true;
                    break;
                }
            }
            blogComment.setIsCommentDianzan(isUserDianZanDiaryComment);

            // 这条评论是否是作者自己评论的
            blogComment.setIsAuthorSelf(comment.getUserAid().equals(blog.getUserAid()));

            // 评论的内容
            blogComment.setCommentContent(comment.getCommentContent());

            // 评论的parentAid
            blogComment.setParentAid(comment.getParentAid());

            // 父评论用户的名字和aid
            if (comment.getParentAid() != null){
                User user = userMapper.selectById(blogCommentMapper.selectById(comment.getParentAid()).getUserAid());
                blogComment.setParentCommentUserAid(user.getAid());
                if (user.getNickName() != null){
                    blogComment.setParentCommentUserName(user.getNickName());
                }else {
                    blogComment.setParentCommentUserName(user.getUserName());
                }
            }else {
                blogComment.setParentCommentUserAid(null);
                blogComment.setParentCommentUserName(null);
            }

            blogCommentList.add(blogComment);
        }

        //最高级别评论集合
        List<com.fzg.common.model.result.blog.BlogComment> roots = new ArrayList<>();
        List<com.fzg.common.model.result.blog.BlogComment> res = new ArrayList<>();

        for (com.fzg.common.model.result.blog.BlogComment comment : blogCommentList) {
            //null表示最高级别的用户
            if(comment.getParentAid() == null)
            {
                roots.add(comment);
            }
        }
        //从最高级别用户开始遍历，递归找到该评论的下级评论，将带有下级的最高级评论放入返回结果中
        for(com.fzg.common.model.result.blog.BlogComment comment :roots)
        {
            comment=buildCommentTree(blogCommentList,comment);
            res.add(comment);
        }
        return res;
    }


    /*
    功能：根据传入的评论，获取该评论的下属集合，将集合赋值给该评论的children属性，返回该评论
     */
    public com.fzg.common.model.result.blog.BlogComment buildCommentTree(List<com.fzg.common.model.result.blog.BlogComment> diaryCommentList, com.fzg.common.model.result.blog.BlogComment comment){
        List<com.fzg.common.model.result.blog.BlogComment> children = new ArrayList<>();
        //遍历查到的所有评论
        for(com.fzg.common.model.result.blog.BlogComment comment1:diaryCommentList)
        {
            //-1代表根节点，无需重复比较
            if(comment1.getParentAid() == null)
                continue;
            //当前评论的上级编号和传入的评论编号相等，表示该评论是传入评论的下级评论
            if(comment1.getParentAid().equals(comment.getCommentAid()))
            {
                //递归调用，再去寻找该评论的下级评论
                comment1=buildCommentTree(diaryCommentList,comment1);
                //当前评论是该评论的一个下级评论，放入children集合内
                children.add(comment1);
            }
        }
        //给该评论的children属性赋值，并返回该评论
        comment.setChildCommentList(children);
        return comment;
    }
}
